#-*- coding:utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
#    d$
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

import time
from datetime import date
from datetime import datetime
from datetime import timedelta
from dateutil import relativedelta

from openerp import api, tools
from openerp.osv import fields, osv
from openerp.tools.translate import _
import openerp.addons.decimal_precision as dp

from openerp.tools.safe_eval import safe_eval as eval

class hr_payslip(osv.osv):
    '''
    Pay Slip
    '''
    _inherit = 'hr.payslip'
    _description = 'Inherit Pay Slip'
     
    def get_worked_day_lines(self, cr, uid, contract_ids, date_from, date_to, context=None):
        """
        @param contract_ids: list of contract id
        @return: returns a list of dict containing the input that should be applied for the given contract between date_from and date_to
        """
        def was_on_leave(employee_id, datetime_day, context=None):
            res = False
            day = datetime_day.strftime("%Y-%m-%d")
            holiday_ids = self.pool.get('hr.holidays').search(cr, uid, [('state','=','validate'),('employee_id','=',employee_id),('type','=','remove'),('date_from','<=',day),('date_to','>=',day)])
            if holiday_ids:
                res = self.pool.get('hr.holidays').browse(cr, uid, holiday_ids, context=context)[0].holiday_status_id.name
            return res
        
        def check_presence(employee_id, datetime_from_day,datetime_to_day, context=None):
            res1 = {}
            total_hours = total_days = 0

            presence_ids = self.pool.get('hr.attendance').search(cr, uid, [('employee_id','=',employee_id),('worked_hours','>','0'),('name','>=',datetime_from_day),('name','<=',datetime_to_day)])

            for details in self.pool.get('hr.attendance').browse(cr, uid, presence_ids, context=context) :
                 total_days +=  1
                 total_hours += details.worked_hours
            
            res1['total_hours'] = total_hours
            res1['total_days'] = total_days     
            return res1
        
        def check_ot(employee_id, datetime_from_day,datetime_to_day, context=None):
            res2 = {}
            total_ot_hours = 0

            overtime_ids = self.pool.get('hr.overtime').search(cr, uid, [('employee_id','=',employee_id),('date_from','>=',datetime_from_day),('date_to','<=',datetime_to_day)])

            for ot in self.pool.get('hr.overtime').browse(cr, uid, overtime_ids, context=context) :
                 total_ot_hours += ot.actual_ot_hours
            
            res2['total_ot_hours'] = total_ot_hours   
            return res2
        
        res = []
        for contract in self.pool.get('hr.contract').browse(cr, uid, contract_ids, context=context):
            if not contract.working_hours:
                #fill only if the contract as a working schedule linked
                continue
            attendances = {
                 'name': _("Normal Working Days paid at 100%"),
                 'sequence': 1,
                 'code': 'WORK100',
                 'number_of_days': 0.0,
                 'number_of_hours': 0.0,
                 'contract_id': contract.id,
            }
            leaves = {}
            day_from = datetime.strptime(date_from,"%Y-%m-%d")
            day_to = datetime.strptime(date_to,"%Y-%m-%d")
            nb_of_days = (day_to - day_from).days + 1
            for day in range(0, nb_of_days):
                working_hours_on_day = self.pool.get('resource.calendar').working_hours_on_day(cr, uid, contract.working_hours, day_from + timedelta(days=day), context)
                if working_hours_on_day:
                    #the employee had to work
                    leave_type = was_on_leave(contract.employee_id.id, day_from + timedelta(days=day), context=context)
                    if leave_type:
                        #if he was on leave, fill the leaves dict
                        if leave_type in leaves:
                            leaves[leave_type]['number_of_days'] += 1.0
                            leaves[leave_type]['number_of_hours'] += working_hours_on_day
                        else:
                            leaves[leave_type] = {
                                'name': leave_type,
                                'sequence': 20,
                                'code': leave_type,
                                'number_of_days': 1.0,
                                'number_of_hours': working_hours_on_day,
                                'contract_id': contract.id,
                            }
                    else:
                        #add the input vals to tmp (increment if existing)
                        attendances['number_of_days'] += 1.0
                        attendances['number_of_hours'] += working_hours_on_day

            presence_array = {}
            presence = check_presence(contract.employee_id.id, str(day_from), str(day_to), context=context)
            if presence:
                presence_array = {
                     'name': _("Presences"),
                     'sequence': 2,
                     'code': 'PRESENCES',
                     'number_of_days': presence['total_days'],
                     'number_of_hours': presence['total_hours'],
                     'contract_id': contract.id,
                }
            else :
                presence_array = {
                     'name': _("Presences"),
                     'sequence': 2,
                     'code': 'PRESENCES',
                     'number_of_days': 0.0,
                     'number_of_hours':0.0,
                     'contract_id': contract.id,  
                }     
            
            overtime_array = {}
            overtime = check_ot(contract.employee_id.id, str(day_from), str(day_to), context=context)
            if overtime:
                overtime_array = {
                     'name': _("Overtime"),
                     'sequence': 3,
                     'code': 'OVERTIME',
                     'number_of_days': 0,
                     'number_of_hours': overtime['total_ot_hours'],
                     'contract_id': contract.id,
                }
            else :
                  overtime_array = {
                     'name': _("Overtime"),
                     'sequence': 3,
                     'code': 'OVERTIME',
                     'number_of_days': 0.0,
                     'number_of_hours':0.0,
                     'contract_id': contract.id,  
                 }    
                           
            transport_array ={}
            transport_array = {
                     'name': _("Transport"),
                     'sequence': 4,
                     'code': 'TRANSPORT',
                     'number_of_days': presence['total_days'],
                     'number_of_hours':0.0,
                     'contract_id': contract.id,  
                 } 
            incentive_array ={}
            incentive_array = {
                     'name': _("Incentive"),
                     'sequence': 6,
                     'code': 'INCENTIVE',
                     'number_of_days': presence['total_days'],
                     'number_of_hours':0.0,
                     'contract_id': contract.id,  
                 } 
            meal_allowance_array ={}
            meal_allowance_array = {
                     'name': _("Meal Allowance"),
                     'sequence': 7,
                     'code': 'MEAL_ALLOWANCE',
                     'number_of_days': presence['total_days'],
                     'number_of_hours':0.0,
                     'contract_id': contract.id,  
                 } 
                    
            leaves = [value for key,value in leaves.items()]
            res += [attendances] + [presence_array] + [overtime_array] + [transport_array] + [incentive_array] +  [meal_allowance_array] + leaves    
        return res
#     
# class hr_payslip_line(osv.osv):
#     '''
#     Payslip Line
#     '''
# 
#     _name = 'hr.payslip.line'
#     _inherit = 'hr.salary.rule'
#     _description = 'Payslip Line'
#     _order = 'contract_id, sequence'
# 
#     def _calculate_total(self, cr, uid, ids, name, args, context):
#         if not ids: return {}
#         res = {}
#         for line in self.browse(cr, uid, ids, context=context):
#             res[line.id] = float(line.quantity) * line.amount * line.rate / 100
#         
#         print res
#         return res
# 
#     _columns = {
#         'slip_id':fields.many2one('hr.payslip', 'Pay Slip', required=True, ondelete='cascade'),
#         'salary_rule_id':fields.many2one('hr.salary.rule', 'Rule', required=True),
#         'employee_id':fields.many2one('hr.employee', 'Employee', required=True),
#         'contract_id':fields.many2one('hr.contract', 'Contract', required=True, select=True),
#         'rate': fields.float('Rate (%)', digits_compute=dp.get_precision('Payroll Rate')),
#         'amount': fields.float('Amount', digits_compute=dp.get_precision('Payroll')),
#         'quantity': fields.float('Quantity', digits_compute=dp.get_precision('Payroll')),
#         'total': fields.function(_calculate_total, method=True, type='float', string='Total nyaaaa', digits_compute=dp.get_precision('Payroll'),store=True ),
#     }
# 
#     _defaults = {
#         'quantity': 1.0,
#         'rate': 100.0,
#     }


# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
